/*!
 * WYSIWYG UBB Editor support for xhEditor
 * @requires xhEditor
 *
 * @author Yanis.Wang<yanis.wang@gmail.com>
 * @site http://xheditor.com/
 * @licence LGPL(http://www.opensource.org/licenses/lgpl-license.php)
 *
 * @Version: 0.9.12 (build 120228)
 */

function ubb2html(sUBB) {
  var i, sHtml = String(sUBB),
    arrcode = new Array(),
    cnum = 0;
  var arrFontsize = ['10px', '13px', '16px', '18px', '24px', '32px', '48px'];

  /*sHtml = sHtml.replace(/[<>&"]/g, function(c) {
    return {
      '<': '&lt;',
      '>': '&gt;',
      '&': '&amp;',
      '"': '&quot;'
    }[c];
  });*/
  sHtml = sHtml.replace(/\r?\n/g, "<br />");

  sHtml = sHtml.replace(/\[code\s*(?:=\s*([^\]]+?))?\]([\s\S]*?)\[\/code\]/ig, function(all, t, c) { //code特殊处理
    cnum++;
    arrcode[cnum] = all;
    return "[\tubbcodeplace_" + cnum + "\t]";
  });

  sHtml = sHtml.replace(/\[(\/?)(b|u|i|s|sup|sub)\]/ig, '<$1$2>');
  sHtml = sHtml.replace(/\[color\s*=\s*([^\]"]+?)(?:"[^\]]*?)?\s*\]/ig, '<font color="$1">');
  sHtml = sHtml.replace(/\[font\s*=\s*([^\]"]+?)(?:"[^\]]*?)?\s*\]/ig, '<font face="$1">');
  sHtml = sHtml.replace(/\[\/(color|font)\]/ig, '</font>');
  sHtml = sHtml.replace(/\[size\s*=\s*([^\]"]+?)(?:"[^\]]*?)?\s*\]/ig, function(all, size) {
    if (size.match(/^\d+$/)) size = arrFontsize[size - 1];
    return '<span style="font-size:' + size + ';">';
  });
  sHtml = sHtml.replace(/\[back\s*=\s*([^\]"]+?)(?:"[^\]]*?)?\s*\]/ig, '<span style="background-color:$1;">');
  sHtml = sHtml.replace(/\[\/(size|back)\]/ig, '</span>');
  for (i = 0; i < 3; i++) sHtml = sHtml.replace(/\[align\s*=\s*([^\]"]+?)(?:"[^\]]*?)?\s*\](((?!\[align(?:\s+[^\]]+)?\])[\s\S])*?)\[\/align\]/ig, '<p align="$1">$2</p>');
  sHtml = sHtml.replace(/\[img\]\s*(((?!")[\s\S])+?)(?:"[\s\S]*?)?\s*\[\/img\]/ig, '<img src="$1" alt="" />');
  sHtml = sHtml.replace(/\[img\s*=([^,\]]*)(?:\s*,\s*(\d*%?)\s*,\s*(\d*%?)\s*)?(?:,?\s*(\w+))?\s*\]\s*(((?!")[\s\S])+?)(?:"[\s\S]*)?\s*\[\/img\]/ig, function(all, alt, p1, p2, p3, src) {
    var str = '<img src="' + src + '" alt="' + alt + '"',
      a = p3 ? p3 : (!isNum(p1) ? p1 : '');
    if (isNum(p1)) str += ' width="' + p1 + '"';
    if (isNum(p2)) str += ' height="' + p2 + '"'
    if (a) str += ' align="' + a + '"';
    str += ' />';
    return str;
  });
  sHtml = sHtml.replace(/\[emot\s*=\s*([^\]"]+?)(?:"[^\]]*?)?\s*\/\]/ig, '<img emot="$1" />');
  sHtml = sHtml.replace(/\[url\]\s*(((?!")[\s\S])*?)(?:"[\s\S]*?)?\s*\[\/url\]/ig, '<a href="$1" target="_blank">$1</a>');
  sHtml = sHtml.replace(/\[url\s*=\s*([^\]"]+?)(?:"[^\]]*?)?\s*\]\s*([\s\S]*?)\s*\[\/url\]/ig, '<a href="$1" target="_blank">$2</a>');
  sHtml = sHtml.replace(/\[email\]\s*(((?!")[\s\S])+?)(?:"[\s\S]*?)?\s*\[\/email\]/ig, '<a href="mailto:$1">$1</a>');
  sHtml = sHtml.replace(/\[email\s*=\s*([^\]"]+?)(?:"[^\]]*?)?\s*\]\s*([\s\S]+?)\s*\[\/email\]/ig, '<a href="mailto:$1">$2</a>');
  sHtml = sHtml.replace(/\[quote\]/ig, '<blockquote>');
  sHtml = sHtml.replace(/\[\/quote\]/ig, '</blockquote>');
  /*sHtml=sHtml.replace(/\[flash\s*(?:=\s*(\d+)\s*,\s*(\d+)\s*)?\]\s*(((?!")[\s\S])+?)(?:"[\s\S]*?)?\s*\[\/flash\]/ig,function(all,w,h,url){
		if(!w)w=480;if(!h)h=400;
		return '<embed type="application/x-shockwave-flash" src="'+url+'" wmode="opaque" quality="high" bgcolor="#ffffff" menu="false" play="true" loop="true" width="'+w+'" height="'+h+'"/>';
	});
  sHtml=sHtml.replace(/\[media\s*(?:=\s*(\d+)\s*,\s*(\d+)\s*(?:,\s*(\d+)\s*)?)?\]\s*(((?!")[\s\S])+?)(?:"[\s\S]*?)?\s*\[\/media\]/ig,function(all,w,h,play,url){
		if(!w)w=480;if(!h)h=400;
		return '<embed type="application/x-mplayer2" src="'+url+'" enablecontextmenu="false" autostart="'+(play=='1'?'true':'false')+'" width="'+w+'" height="'+h+'"/>';
	});*/
  sHtml = sHtml.replace(/\[table\s*(?:=\s*(\d{1,4}%?)\s*(?:,\s*([^\]"]+)(?:"[^\]]*?)?)?)?\s*\]/ig, function(all, w, b) {
    var str = '<table';
    if (w) str += ' width="' + w + '"';
    if (b) str += ' bgcolor="' + b + '"';
    return str + '>';
  });
  sHtml = sHtml.replace(/\[tr\s*(?:=\s*([^\]"]+?)(?:"[^\]]*?)?)?\s*\]/ig, function(all, bg) {
    return '<tr' + (bg ? ' bgcolor="' + bg + '"' : '') + '>';
  });
  sHtml = sHtml.replace(/\[td\s*(?:=\s*(\d{1,2})\s*,\s*(\d{1,2})\s*(?:,\s*(\d{1,4}%?))?)?\s*\]/ig, function(all, col, row, w) {
    return '<td' + (col > 1 ? ' colspan="' + col + '"' : '') + (row > 1 ? ' rowspan="' + row + '"' : '') + (w ? ' width="' + w + '"' : '') + '>';
  });
  sHtml = sHtml.replace(/\[\/(table|tr|td)\]/ig, '</$1>');

  sHtml = sHtml.replace(/\[\*\]((?:(?!\[\*\]|\[\/list\]|\[list\s*(?:=[^\]]+)?\])[\s\S])+)/ig, '<li>$1</li>');
  sHtml = sHtml.replace(/\[list\s*(?:=\s*([^\]"]+?)(?:"[^\]]*?)?)?\s*\]/ig, function(all, type) {
    var str = '<ul';
    if (type) str += ' type="' + type + '"';
    return str + '>';
  });
  sHtml = sHtml.replace(/\[\/list\]/ig, '</ul>');
  sHtml = sHtml.replace(/\[hr\/\]/ig, '<hr />');

  for (i = 1; i <= cnum; i++) sHtml = sHtml.replace("[\tubbcodeplace_" + i + "\t]", arrcode[i]);

  sHtml = sHtml.replace(/(^|<\/?\w+(?:\s+[^>]*?)?>)([^<$]+)/ig, function(all, tag, text) {
    return tag + text.replace(/[\t ]/g, function(c) {
      return {
        '\t': '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;',
        ' ': '&nbsp;'
      }[c];
    });
  });

  function isNum(s) {
    if (s != null && s != '') return !isNaN(s);
    else return false;
  }

  return sHtml;
}

function html2ubb(sHtml) {
  var regSrc = /\s+src\s*=\s*(["']?)\s*(.+?)\s*\1(\s|$)/i,
    regWidth = /\s+width\s*=\s*(["']?)\s*(\d+(?:\.\d+)?%?)\s*\1(\s|$)/i,
    regHeight = /\s+height\s*=\s*(["']?)\s*(\d+(?:\.\d+)?%?)\s*\1(\s|$)/i,
    regBg = /(?:background|background-color|bgcolor)\s*[:=]\s*(["']?)\s*((rgb\s*\(\s*\d{1,3}%?,\s*\d{1,3}%?\s*,\s*\d{1,3}%?\s*\))|(#[0-9a-f]{3,6})|([a-z]{1,20}))\s*\1/i
  var i, sUBB = String(sHtml),
    arrcode = new Array(),
    cnum = 0;

  sUBB = sUBB.replace(/\s*\r?\n\s*/g, '');

  sUBB = sUBB.replace(/<(script|style)(\s+[^>]*?)?>[\s\S]*?<\/\1>/ig, '');
  sUBB = sUBB.replace(/<!--[\s\S]*?-->/ig, '');

  sUBB = sUBB.replace(/<br(\s+[^>]*)?\/?>/ig, "\r\n");

  sUBB = sUBB.replace(/\[code\s*(=\s*([^\]]+?))?\]([\s\S]*?)\[\/code\]/ig, function(all, t, c) { //code特殊处理
    cnum++;
    arrcode[cnum] = all;
    return "[\tubbcodeplace_" + cnum + "\t]";
  });

  sUBB = sUBB.replace(/<(\/?)(b|u|i|s)(\s+[^>]*?)?>/ig, '[$1$2]');
  sUBB = sUBB.replace(/<(\/?)strong(\s+[^>]*?)?>/ig, '[$1b]');
  sUBB = sUBB.replace(/<(\/?)em(\s+[^>]*?)?>/ig, '[$1i]');
  sUBB = sUBB.replace(/<(\/?)(strike|del)(\s+[^>]*?)?>/ig, '[$1s]');
  sUBB = sUBB.replace(/<(\/?)(sup|sub)(\s+[^>]*?)?>/ig, '[$1$2]');

  //font转ubb

  function font2ubb(all, tag, attrs, content) {
    if (!attrs) return content;
    var arrStart = [],
      arrEnd = [];
    var match;
    match = attrs.match(/ face\s*=\s*"\s*([^"]+)\s*"/i);
    if (match) {
      arrStart.push('[font=' + match[1] + ']');
      arrEnd.push('[/font]');
    }
    match = attrs.match(/ size\s*=\s*"\s*(\d+)\s*"/i);
    if (match) {
      arrStart.push('[size=' + match[1] + ']');
      arrEnd.push('[/size]');
    }
    match = attrs.match(/ color\s*=\s*"\s*([^"]+)\s*"/i);
    if (match) {
      arrStart.push('[color=' + formatColor(match[1]) + ']');
      arrEnd.push('[/color]');
    }
    return arrStart.join('') + content + arrEnd.join('');
  }
  sUBB = sUBB.replace(/<(font)(\s+[^>]*?)?>(((?!<\1(\s+[^>]*?)?>)[\s\S]|<\1(\s+[^>]*?)?>((?!<\1(\s+[^>]*?)?>)[\s\S]|<\1(\s+[^>]*?)?>((?!<\1(\s+[^>]*?)?>)[\s\S])*?<\/\1>)*?<\/\1>)*?)<\/\1>/ig, font2ubb); //第3层
  sUBB = sUBB.replace(/<(font)(\s+[^>]*?)?>(((?!<\1(\s+[^>]*?)?>)[\s\S]|<\1(\s+[^>]*?)?>((?!<\1(\s+[^>]*?)?>)[\s\S])*?<\/\1>)*?)<\/\1>/ig, font2ubb); //第2层
  sUBB = sUBB.replace(/<(font)(\s+[^>]*?)?>(((?!<\1(\s+[^>]*?)?>)[\s\S])*?)<\/\1>/ig, font2ubb); //最里层

  for (i = 0; i < 3; i++) sUBB = sUBB.replace(/<(span)(?:\s+[^>]*?)?\s+style\s*=\s*"((?:[^"]*?;)*\s*(?:font-family|font-size|color|background|background-color)\s*:[^"]*)"(?: [^>]+)?>(((?!<\1(\s+[^>]*?)?>)[\s\S]|<\1(\s+[^>]*?)?>((?!<\1(\s+[^>]*?)?>)[\s\S]|<\1(\s+[^>]*?)?>((?!<\1(\s+[^>]*?)?>)[\s\S])*?<\/\1>)*?<\/\1>)*?)<\/\1>/ig, function(all, tag, style, content) {
    var face = style.match(/(?:^|;)\s*font-family\s*:\s*([^;]+)/i),
      size = style.match(/(?:^|;)\s*font-size\s*:\s*([^;]+)/i),
      color = style.match(/(?:^|;)\s*color\s*:\s*([^;]+)/i),
      back = style.match(/(?:^|;)\s*(?:background|background-color)\s*:\s*([^;]+)/i),
      str = content;
    var arrStart = [],
      arrEnd = [];
    if (face) {
      arrStart.push('[font=' + face[1] + ']');
      arrEnd.push('[/font]');
    }
    if (size) {
      arrStart.push('[size=' + size[1] + ']');
      arrEnd.push('[/size]');
    }
    if (color) {
      arrStart.push('[color=' + formatColor(color[1]) + ']');
      arrEnd.push('[/color]');
    }
    if (back) {
      arrStart.push('[back=' + formatColor(back[1]) + ']');
      arrEnd.push('[/back]');
    }
    return arrStart.join('') + str + arrEnd.join('');
  });

  function formatColor(c) {
    var matchs;
    if (matchs = c.match(/\s*rgb\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)/i)) {
      c = (matchs[1] * 65536 + matchs[2] * 256 + matchs[3] * 1).toString(16);
      while (c.length < 6) c = '0' + c;
      c = '#' + c;
    }
    c = c.replace(/^#([0-9a-f])([0-9a-f])([0-9a-f])$/i, '#$1$1$2$2$3$3');
    return c;
  }
  for (i = 0; i < 3; i++) sUBB = sUBB.replace(/<(div|p)(?:\s+[^>]*?)?[\s"';]\s*(?:text-)?align\s*[=:]\s*(["']?)\s*(left|center|right)\s*\2[^>]*>(((?!<\1(\s+[^>]*?)?>)[\s\S])+?)<\/\1>/ig, '[align=$3]$4[/align]');
  for (i = 0; i < 3; i++) sUBB = sUBB.replace(/<(center)(?:\s+[^>]*?)?>(((?!<\1(\s+[^>]*?)?>)[\s\S])*?)<\/\1>/ig, '[align=center]$2[/align]');
  for (i = 0; i < 3; i++) sUBB = sUBB.replace(/<(p|div)(?:\s+[^>]*?)?\s+style\s*=\s*"(?:[^;"]*;)*\s*text-align\s*:([^;"]*)[^"]*"(?: [^>]+)?>(((?!<\1(\s+[^>]*?)?>)[\s\S]|<\1(\s+[^>]*?)?>((?!<\1(\s+[^>]*?)?>)[\s\S]|<\1(\s+[^>]*?)?>((?!<\1(\s+[^>]*?)?>)[\s\S])*?<\/\1>)*?<\/\1>)*?)<\/\1>/ig, function(all, tag, align, content) {
    return '[align=' + align + ']' + content + '[/align]';
  });
  sUBB = sUBB.replace(/<a(?:\s+[^>]*?)?\s+href=(["'])\s*(.+?)\s*\1[^>]*>\s*([\s\S]*?)\s*<\/a>/ig, function(all, q, url, text) {
    if (!(url && text)) return '';
    var tag = 'url',
      str;
    if (url.match(/^mailto:/i)) {
      tag = 'email';
      url = url.replace(/mailto:(.+?)/i, '$1');
    }
    str = '[' + tag;
    if (url != text) str += '=' + url;
    return str + ']' + text + '[/' + tag + ']';
  });
  sUBB = sUBB.replace(/<img(\s+[^>]*?)\/?>/ig, function(all, attr) {
    var emot = attr.match(/\s+emot\s*=\s*(["']?)\s*(.+?)\s*\1(\s|$)/i);
    if (emot) return '[emot=' + emot[2] + '/]';
    var url = attr.match(regSrc),
      alt = attr.match(/\s+alt\s*=\s*(["']?)\s*(.*?)\s*\1(\s|$)/i),
      w = attr.match(regWidth),
      h = attr.match(regHeight),
      align = attr.match(/\s+align\s*=\s*(["']?)\s*(\w+)\s*\1(\s|$)/i),
      str = '[img',
      p = '';
    if (!url) return '';
    p += alt[2];
    if (w || h) p += ',' + (w ? w[2] : '') + ',' + (h ? h[2] : '');
    if (align) p += ',' + align[2];
    if (p) str += '=' + p;
    str += ']' + url[2] + '[/img]';
    return str;
  });
  sUBB = sUBB.replace(/<blockquote(?:\s+[^>]*?)?>/ig, '[quote]');
  sUBB = sUBB.replace(/<\/blockquote>/ig, '[/quote]');
  /*sUBB = sUBB.replace(/<embed((?:\s+[^>]*?)?(?:\s+type\s*=\s*"\s*application\/x-shockwave-flash\s*"|\s+classid\s*=\s*"\s*clsid:d27cdb6e-ae6d-11cf-96b8-4445535400000\s*")[^>]*?)\/?>/ig, function(all, attr) {
    var url = attr.match(regSrc),
      w = attr.match(regWidth),
      h = attr.match(regHeight),
      str = '[flash';
    if (!url) return '';
    if (w && h) str += '=' + w[2] + ',' + h[2];
    str += ']' + url[2];
    return str + '[/flash]';
  });
  sUBB = sUBB.replace(/<embed((?:\s+[^>]*?)?(?:\s+type\s*=\s*"\s*application\/x-mplayer2\s*"|\s+classid\s*=\s*"\s*clsid:6bf52a52-394a-11d3-b153-00c04f79faa6\s*")[^>]*?)\/?>/ig, function(all, attr) {
    var url = attr.match(regSrc),
      w = attr.match(regWidth),
      h = attr.match(regHeight),
      p = attr.match(/\s+autostart\s*=\s*(["']?)\s*(.+?)\s*\1(\s|$)/i),
      str = '[media',
      auto = '0';
    if (!url) return '';
    if (p)
      if (p[2] == 'true') auto = '1';
    if (w && h) str += '=' + w[2] + ',' + h[2] + ',' + auto;
    str += ']' + url[2];
    return str + '[/media]';
  });*/
  sUBB = sUBB.replace(/<table(\s+[^>]*?)?>/ig, function(all, attr) {
    var str = '[table';
    if (attr) {
      var w = attr.match(regWidth),
        b = attr.match(regBg);
      if (w) {
        str += '=' + w[2];
        if (b) str += ',' + b[2];
      }
    }
    return str + ']';
  });
  sUBB = sUBB.replace(/<tr(\s+[^>]*?)?>/ig, function(all, attr) {
    var str = '[tr';
    if (attr) {
      var bg = attr.match(regBg)
      if (bg) str += '=' + bg[2];
    }
    return str + ']';
  });
  sUBB = sUBB.replace(/<(?:th|td)(\s+[^>]*?)?>/ig, function(all, attr) {
    var str = '[td';
    if (attr) {
      var col = attr.match(/\s+colspan\s*=\s*(["']?)\s*(\d+)\s*\1(\s|$)/i),
        row = attr.match(/\s+rowspan\s*=\s*(["']?)\s*(\d+)\s*\1(\s|$)/i),
        w = attr.match(regWidth);
      col = col ? col[2] : 1;
      row = row ? row[2] : 1;
      if (col > 1 || row > 1 || w) str += '=' + col + ',' + row;
      if (w) str += ',' + w[2];
    }
    return str + ']';
  });
  sUBB = sUBB.replace(/<\/(table|tr)>/ig, '[/$1]');
  sUBB = sUBB.replace(/<\/(th|td)>/ig, '[/td]');

  sUBB = sUBB.replace(/<ul(\s+[^>]*?)?>/ig, function(all, attr) {
    var t;
    if (attr) t = attr.match(/\s+type\s*=\s*(["']?)\s*(.+?)\s*\1(\s|$)/i);
    return '[list' + (t ? '=' + t[2] : '') + ']';
  });
  sUBB = sUBB.replace(/<ol(\s+[^>]*?)?>/ig, '[list=1]');
  sUBB = sUBB.replace(/<li(\s+[^>]*?)?>/ig, '[*]');
  sUBB = sUBB.replace(/<\/li>/ig, '');
  sUBB = sUBB.replace(/<\/(ul|ol)>/ig, '[/list]');
  sUBB = sUBB.replace(/<h([1-6])(\s+[^>]*?)?>/ig, function(all, n) {
    return '\r\n\r\n[size=' + (7 - n) + '][b]'
  });
  sUBB = sUBB.replace(/<\/h[1-6]>/ig, '[/b][/size]\r\n\r\n');
  sUBB = sUBB.replace(/<address(\s+[^>]*?)?>/ig, '\r\n[i]');
  sUBB = sUBB.replace(/<\/address>/ig, '[i]\r\n');
  sUBB = sUBB.replace(/<hr(\s+[^>]*?)?\/>/ig, '[hr/]');

  for (i = 0; i < 3; i++) sUBB = sUBB.replace(/<(p)(?:\s+[^>]*?)?>(((?!<\1(\s+[^>]*?)?>)[\s\S]|<\1(\s+[^>]*?)?>((?!<\1(\s+[^>]*?)?>)[\s\S]|<\1(\s+[^>]*?)?>((?!<\1(\s+[^>]*?)?>)[\s\S])*?<\/\1>)*?<\/\1>)*?)<\/\1>/ig, "\r\n\r\n$2\r\n\r\n");
  for (i = 0; i < 3; i++) sUBB = sUBB.replace(/<(div)(?:\s+[^>]*?)?>(((?!<\1(\s+[^>]*?)?>)[\s\S]|<\1(\s+[^>]*?)?>((?!<\1(\s+[^>]*?)?>)[\s\S]|<\1(\s+[^>]*?)?>((?!<\1(\s+[^>]*?)?>)[\s\S])*?<\/\1>)*?<\/\1>)*?)<\/\1>/ig, "\r\n$2\r\n");

  sUBB = sUBB.replace(/((\s|&nbsp;)*\r?\n){3,}/g, "\r\n\r\n"); //限制最多2次换行
  sUBB = sUBB.replace(/^((\s|&nbsp;)*\r?\n)+/g, ''); //清除开头换行
  sUBB = sUBB.replace(/((\s|&nbsp;)*\r?\n)+$/g, ''); //清除结尾换行

  for (i = 1; i <= cnum; i++) sUBB = sUBB.replace("[\tubbcodeplace_" + i + "\t]", arrcode[i]);

  sUBB = sUBB.replace(/<[^<>]+?>/g, ''); //删除所有HTML标签
  /*var arrEntities = {
    'lt': '<',
    'gt': '>',
    'nbsp': ' ',
    'amp': '&',
    'quot': '"'
  };
  sUBB = sUBB.replace(/&(lt|gt|nbsp|amp|quot);/ig, function(all, t) {
    return arrEntities[t];
  });*/

  //清除空内容的UBB标签
  sUBB = sUBB.replace(/\[([a-z]+)(?:=[^\[\]]+)?\]\s*\[\/\1\]/ig, '');

  return sUBB;
}